

import 'dart:convert';
import 'dart:core';
import 'dart:math';
import 'package:ble2025_plugin/bean/models.dart';
import 'package:ble2025_plugin/utils/ble_const.dart';
import 'package:ble2025_plugin/utils/device_cmd.dart';
import 'package:ble2025_plugin/utils/resolve_util.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';

class BleSDK {
  static const int DATA_READ_START = 0;
  static const int DATA_READ_CONTINUE = 2;
  static const int DATA_DELETE = 99;
  static const int DistanceMode_MILE = 0x81;
  static const int DistanceMode_KM = 0x80;
  static const int TimeMode_12h = 0x81;
  static const int TimeMode_24h = 0x80;
  static const int WristOn_Enable = 0x81;
  static const int WristOn_DisEnable = 0x80;
  static const int TempUnit_C =  0x80;
  static const int TempUnit_F =  0x81;
  static const String TAG = "BleSDK";
  static bool isRuning = false;


  static List<int> _generateValue(int size) {
    final List<int> data = List<int>.generate(size, (int index) {
      return 0;
    });
    return data;
  }

  static int _hexByte2Int(int b, int count) {
    return (b & 0xff) * pow(256, count) as int;
  }

  /// 初始化要发送的数据，16个字节，没有设置的位置都默认为0
  /// Initialize the data to be sent, 16 bytes, and default to 0 for positions that are not set
  static List<int> _generateInitValue() {
    return _generateValue(16);
  }

  /// copying array of data
  static void arrayCopy(
      List<int> source, int srcPos, List<int> dest, int destPos, int length) {
    for (int i = 0; i < length; i++) {
      dest[destPos + i] = source[srcPos + i];
    }
  }

  /// message content needed to be sent is converted to List<int>
  static List<int> _getInfoValue(String info, int maxLength) {
    if (info.isEmpty) return [];
    final List<int> nameBytes = utf8.encode(info);
    if (nameBytes.length >= maxLength) {
      /// two commands in total 32 bytes, with only 24 bytes of content.
      /// （32-2*（1cmd+1 Message type + 1 length + 1 validation））
      final List<int> real = List<int>.generate(maxLength, (int index) {
        return 0;
      });
      final List<int> chars = info.codeUnits;
      int length = 0;
      for (int i = 0; i < chars.length; i++) {
        final String s = chars[i].toString();
        final List<int> nameB = utf8.encode(s);
        if (length + nameB.length == maxLength) {
          arrayCopy(nameBytes, 0, real, 0, real.length);
          return real;
        } else if (length + nameB.length > maxLength) {
          /// >24 will result in a byte not being sent to the lower machine causing garbled code
          arrayCopy(nameBytes, 0, real, 0, length);
          return real;
        }
        length += nameB.length;
      }
    }
    return nameBytes;
  }

  /// crc验证
  /// crc validation
  static void _crcValue(List<int> list) {
    int crcValue = 0;
    for (final int value in list) {
      crcValue += value;
    }
    list[15] = crcValue & 0xff;
  }

  ///删除所有闹钟
  ///Delete all alarms
  static Uint8List deleteAllClock() {
    List<int> value = _generateInitValue();
    value[0] = 0x57;
    value[1] =  0x99;
    _crcValue(value);
    return Uint8List.fromList(value);
  }

  /// 十进制转bcd码（23 -> 0x23）
  /// Decimal to bcd code (23 ->0x23)
  static int _getBcdValue(int value) {
    String data = value.toString();
    if (data.length > 2) data = data.substring(2);
    return int.parse(data, radix: 16);
  }



  ///设置闹钟
  ///set alarm
  static Uint8List setClockData(List<Clock> clockList) {
    int size = clockList.length;
    int length = 39;
    List<int> totalValue = _generateValue(length * size + 2);
    for (int i = 0; i < clockList.length; i++) {
      Clock clock = clockList[i];
      List<int> value = _generateValue(length);
      String content = clock.content;
      List<int> infoValue = _getInfoValue(content, 30);
      value[0] = DeviceConst.CMD_Set_Clock;
      value[1] =  size;
      value[2] =  clock.number!;
      value[3] =  (clock.enable ? 1 : 0);
      value[4] =  clock.type;
      value[5] = _getBcdValue(clock.hour);
      value[6] = _getBcdValue(clock.minute);
      value[7] =  ResolveUtil.getWeekInt(clock.weeks);
      value[8] =  (infoValue.isEmpty ? 1 : infoValue.length);
      arrayCopy(infoValue, 0, value, 9, infoValue.length);
      arrayCopy(value, 0, totalValue, i * length, value.length);
    }
    totalValue[totalValue.length - 2] = DeviceConst.CMD_Set_Clock;
    totalValue[totalValue.length - 1] =  0xff;
    return Uint8List.fromList(totalValue);
  }

  ///运动模式开关
  ///Sport mode switch
  static Uint8List EnterActivityMode(int activityMode, int WorkMode) {
    List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_Start_EXERCISE;
    value[1] =  WorkMode;
    value[2] =  activityMode;
    _crcValue(value);
    return Uint8List.fromList(value);
  }


  ///发送运动模式心跳包(配合"EnterActivityMode"使用)
  ///当手环是通过APP进入多运动模式后，APP必须每隔1秒发送一个数据给手环，否则手环会退出多运动模式
  ///Send a sports mode heartbeat packet (used in conjunction with 'EnterActivityMode')
  ///When the bracelet enters multi sport mode through the APP, the APP must send data to the bracelet every 1 second, otherwise the bracelet will exit multi sport mode
  static Uint8List sendHeartPackage(double distance, int space, int rssi) {
    List<int> value = _generateInitValue();
    final bData = ByteData(8);
    int min = space ~/ 60;
    int second = space % 60;
    bData.setFloat32(0, distance, Endian.little);
    final List<int> distanceValue = bData.buffer.asUint8List(0, 4);
    value[0] = DeviceConst.CMD_heart_package;
    arrayCopy(distanceValue, 0, value, 1, distanceValue.length);
    value[5] =  min;
    value[6] =  second;
    value[7] =  rssi;
    _crcValue(value);
    return Uint8List.fromList(value);
  }


  static Map DataParsingWithData(List<int> value) {
    switch (value[0]) {
      case DeviceConst.CMD_Set_Goal:
        return ResolveUtil.setMethodSuccessful(BleConst.SetStepGoal);
      case DeviceConst.CMD_Set_UseInfo:
        return ResolveUtil.setMethodSuccessful(BleConst.SetPersonalInfo);
      case DeviceConst.CMD_Set_Name:
        break;
      case DeviceConst.CMD_Set_MOT_SIGN:
        return ResolveUtil.setMethodSuccessful(BleConst.SetMotorVibrationWithTimes);
      case DeviceConst.CMD_Set_DeviceInfo:
        return ResolveUtil.setMethodSuccessful(BleConst.SetDeviceInfo);
      case DeviceConst.CMD_Set_AutoHeart:
        return ResolveUtil.setMethodSuccessful(BleConst.SetAutomaticHRMonitoring);
      case DeviceConst.CMD_Set_ActivityAlarm:
        return ResolveUtil.setMethodSuccessful(BleConst.SetSedentaryReminder);
      case DeviceConst.CMD_Set_DeviceID:
        return ResolveUtil.setMacSuccessful();
      case DeviceConst.CMD_Start_EXERCISE:
        return ResolveUtil.setMethodSuccessful(BleConst.EnterActivityMode);
      case DeviceConst.CMD_Set_TemperatureCorrection:
        if (value[2] != 0 && value[3] != 0) {
          return ResolveUtil.GetTemperatureCorrectionValue(value);
        }else{
          return ResolveUtil.setMethodSuccessful(BleConst.CMD_Set_TemperatureCorrection);
        }
      case DeviceConst.CMD_HeartPackageFromDevice:
        return ResolveUtil.getActivityExerciseData(value);
      case DeviceConst.CMD_SET_TIME:
        return ResolveUtil.setTimeSuccessful(value);
      case DeviceConst.CMD_Get_SPORTData:
        return ResolveUtil.getExerciseData(value);
      case DeviceConst.CMD_GET_TIME:
        return ResolveUtil.getDeviceTime(value);
      case DeviceConst.CMD_GET_USERINFO:
        return ResolveUtil.getUserInfo(value);
      case DeviceConst.CMD_Get_DeviceInfo:
        return ResolveUtil.getDeviceInfo(value);
      case DeviceConst.CMD_Enable_Activity:
        return ResolveUtil.getActivityData(value);
      case DeviceConst.CMD_Get_Goal:
        return ResolveUtil.getGoal(value);
      case DeviceConst.CMD_Get_BatteryLevel:
        return ResolveUtil.getDeviceBattery(value);
      case DeviceConst.CMD_Get_Address:
        return ResolveUtil.getDeviceAddress(value);
      case DeviceConst.CMD_Get_Version:
        return ResolveUtil.getDeviceVersion(value);
      case DeviceConst.CMD_Get_Name:
        return ResolveUtil.getDeviceName(value);
      case DeviceConst.CMD_Get_AutoHeart:
        return ResolveUtil.getAutoHeart(value);
      case DeviceConst.CMD_Reset:
        return ResolveUtil.Reset();
      case DeviceConst.CMD_Mcu_Reset:
        return ResolveUtil.MCUReset();
      case DeviceConst.CMD_Notify:
        return ResolveUtil.Notify();
      case DeviceConst.CMD_Get_ActivityAlarm:
        return ResolveUtil.getActivityAlarm(value);
      case DeviceConst.CMD_Get_TotalData:
        return ResolveUtil.getTotalStepData(value);
      case DeviceConst.CMD_Get_DetailData:
        return ResolveUtil.getDetailData(value);
      case DeviceConst.CMD_Get_SleepData:
        return ResolveUtil.getSleepData(value);
      case DeviceConst.CMD_Get_HeartData:
        return ResolveUtil.getHeartData(value);
      case DeviceConst.CMD_Get_OnceHeartData:
        return ResolveUtil.getOnceHeartData(value);
      case DeviceConst.CMD_Get_HrvTestData:
        return ResolveUtil.getHrvTestData(value);
      case DeviceConst.CMD_Get_Clock:
        return ResolveUtil.getClockData(value);
      case DeviceConst.CMD_Set_Clock:
        return ResolveUtil.updateClockSuccessful(value);
      case DeviceConst.CMD_Set_NewDeviceInfo:
        return ResolveUtil.setNewDeviceInfo(value);
      case DeviceConst.CMD_Get_NewDeviceInfo:
        return ResolveUtil.getNewDeviceInfo(value);
      case DeviceConst.Enter_photo_modeback:
        return ResolveUtil.enterPhotoModeback(value);
      case DeviceConst.Enter_photo_mode:
        return ResolveUtil.setMethodSuccessful(BleConst.EnterPhotoMode);
      case DeviceConst.Exit_photo_mode:
        return ResolveUtil.setMethodSuccessful(BleConst.BackHomeView);
      case DeviceConst.CMD_ECGQuality:
        return ResolveUtil.eCGQuality(value);
      case DeviceConst.CMD_ECGDATA:
      case DeviceConst.CMD_PPGGDATA:
      break;
      case DeviceConst.Weather:
        return ResolveUtil.setMethodSuccessful(BleConst.Weather);
    case DeviceConst.Braceletdial:
      return ResolveUtil.braceletdial(isRuning,value);
    case DeviceConst.SportMode:
      return ResolveUtil.setMethodSuccessful(BleConst.SportMode);
    case DeviceConst.GetSportMode:
      return ResolveUtil.getSportMode(value);
    case DeviceConst.MeasurementWithType:
      return ResolveUtil.measurementWithType(StartDeviceMeasurementWithType,value);
    case DeviceConst.GPSControlCommand:
      return ResolveUtil.gPSControlCommand(value);
    case DeviceConst.CMD_Get_GPSDATA:
      return ResolveUtil.getHistoryGpsData(value);
    case DeviceConst.Clear_Bracelet_data:
      return ResolveUtil.setMethodSuccessful(BleConst.Clear_Bracelet_data);
    case DeviceConst.CMD_Get_Auto_Blood_oxygen:
      return ResolveUtil.getAutoBloodOxygen(value);
    case DeviceConst.CMD_Get_Blood_oxygen:
      return ResolveUtil.getBloodoxygen(value);
    case  DeviceConst.CMD_SET_SOCIAL:
      if(isSettingSocial){
        return ResolveUtil.setMethodSuccessful(BleConst.SocialdistanceSetting);
      }else{
        return ResolveUtil.setSocial(value);
      }
    case  DeviceConst.Sos:
      return ResolveUtil.setMethodSuccessful(BleConst.Sos);
    case  DeviceConst.Temperature_history:
      return ResolveUtil.getTempData(value);
    case  DeviceConst.GetAxillaryTemperatureDataWithMode:
      return ResolveUtil.getTempDataer(value);
    case DeviceConst.CMD_QrCode:
      return ResolveUtil.getQrCode(value,Qrcode);
    case DeviceConst.GetEcgPpgStatus:
      return ResolveUtil.ECGResult(value);
      case DeviceConst.PregnancyCycle:
        if(pregnancyCycleRead){//读取
          return ResolveUtil.readPregnancyCycle(value);
        }else{//设置
          return ResolveUtil.setMethodSuccessful(BleConst.SetPregnancyCycle);
        }
    case DeviceConst.GetEcgSaveData:
      if(read){
        return ResolveUtil.getEcgHistoryData(value);
      }else {
        return ResolveUtil.setMethodSuccessful(BleConst.DeleteECGdata);
      }
    case DeviceConst.Openecg:
      if(ecgopen){
        if(16 <= value.length){
          return ResolveUtil.ecgData(value);
        }
      }else{
        return ResolveUtil.setMethodSuccessful(BleConst.ECG);
      }
      break;
    case DeviceConst.WomenHealth:
      if(value[1] == 0){//设置
        return ResolveUtil.setMethodSuccessful(BleConst.SetWomenHealth);
      }else{//读取
        return ResolveUtil.readWomenHealth(value);
      }
    case DeviceConst.Closeecg:
      return ResolveUtil.setMethodSuccessful(BleConst.CloseECG);
    case DeviceConst.BloodsugarWithMode:
        int ppi = _hexByte2Int(value[1], 0);
        int ppi2 = _hexByte2Int(value[2], 0);
        if(0==ppi){
          switch (ppi2){
            case 1:
              return ResolveUtil.setMethodSuccessful(BleConst.ppgStartSucessed);
            case 2:
             return ResolveUtil.setMethodSuccessful(BleConst.ppgResult);
            case 3:
              return ResolveUtil.setMethodSuccessful(BleConst.ppgStop);
            case 4:
              return ResolveUtil.setMethodSuccessful(BleConst.ppgMeasurementProgress);
            case 5:
              return ResolveUtil.setMethodSuccessful(BleConst.ppgQuit);
          }
        }else{
          return ResolveUtil.setMethodSuccessful(BleConst.ppgStartFailed);
        }
        break;
    }
    return ResolveUtil.setMethodError(_getBcdValue(value[0]).toString());
  }

  ///血糖
  static Uint8List BloodsugarWithMode(int ppgMode,int ppgStatus) {
    List<int> value = _generateInitValue();
    value[0] = DeviceConst.BloodsugarWithMode;
    value[1] = ppgMode;
    if(2==ppgMode || 4==ppgMode){
      value[2] = ppgStatus;
    }
    _crcValue(value);
    return Uint8List.fromList(value);
  }



  static bool ecgopen = false;
  static Uint8List OpenECGPPG(int level, int time) {
    ecgopen= 0 != level;
    List<int> value = _generateInitValue();
    value[0] = DeviceConst.Openecg;
    value[1] = level;
    value[3] = ((time) & 0xff);
    value[4] = ((time >> 8) & 0xff);
    _crcValue(value);
    return Uint8List.fromList(value);
  }

  static Uint8List stopEcgPPg(){
    List<int> value = _generateInitValue();
    value[0]=DeviceConst.Closeecg;
    _crcValue(value);
    return Uint8List.fromList(value);
  }


  static bool read = false;
  static Uint8List getEcgHistoryData(int days, String dateOfLastData) {
    read=true;
    List<int> value = _generateInitValue();
    value[0] = DeviceConst.GetEcgSaveData;
    value[1] = 0;
    value[2] = days;
    insertDateValue(value, dateOfLastData);
    _crcValue(value);
    return Uint8List.fromList(value);
  }

  static Uint8List deleteEcgHistoryData() {
    read=false;
    List<int> value = _generateInitValue();
    value[0] = DeviceConst.GetEcgSaveData;
    value[1] = 0x99;
    _crcValue(value);
    return Uint8List.fromList(value);
  }


  static void insertDateValue(List<int> value, String time) {
    if (time.isNotEmpty && time.length > 8) {
      List<String> timeArray = time.split(" ");
      String INDEX;
      if (time.contains("-")) {
        INDEX = "-";
      } else {
        INDEX = "\\.";
      }
      int year = int.parse(timeArray[0].split(INDEX)[0]);
      int month = int.parse(timeArray[0].split(INDEX)[1]);
      int day = int.parse(timeArray[0].split(INDEX)[2]);
      int hour = int.parse(timeArray[1].split(":")[0]);
      int min = int.parse(timeArray[1].split(":")[1]);
      int second = int.parse(timeArray[1].split(":")[2]);
      value[4] = _getBcdValue(year);
      value[5] = _getBcdValue(month);
      value[6] = _getBcdValue(day);
      value[7] = _getBcdValue(hour);
      value[8] = _getBcdValue(min);
      value[9] = _getBcdValue(second);
    }
  }

  ///获得睡眠详细数据
  ///0:读最近的睡眠详细数据 1：读指定位置的睡眠详细数据 2：继续上次读的位置下一段数据 99: 删除睡眠数据
  ///Obtain detailed sleep data
  ///0: Read the latest sleep detailed data 1: Read the sleep detailed data at the specified location 2: Continue with the next data segment at the last read location 99: Delete sleep data
  static Uint8List GetDetailSleepDataWithMode(int mode) {
    List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_Get_SleepData;
    if(99==mode){
      value[1] =  0x99;
    }else{
      value[1] =  mode;
    }
    _crcValue(value);
    return Uint8List.fromList(value);
  }


  static Uint8List GetGpsData(int index) {
    List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_Get_GPSDATA;
    value[1] =  index;
    _crcValue(value);
    return Uint8List.fromList(value);
  }

  ///一键清除手环历史数据，但不休眠
  ///One click to clear the historical data of the bracelet, but do not sleep
  static Uint8List ClearBraceletData() {
    List<int> value = _generateInitValue();
    value[0] = DeviceConst.Clear_Bracelet_data;
    _crcValue(value);
    return Uint8List.fromList(value);
  }

  ///Sos功能
  ///So function
  static Uint8List Sos() {
    List<int> value = _generateInitValue();
    value[0] = DeviceConst.Sos;
    _crcValue(value);
    return Uint8List.fromList(value);
  }

  ///传送马达振动信号
  ///Transmit motor vibration signal
  static Uint8List MotorVibrationWithTimes(int times) {
    List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_Set_MOT_SIGN;
    value[1] =  times;
    _crcValue(value);
    return Uint8List.fromList(value);
  }

  ///开始实时计步
  ///Start real time step
  static Uint8List RealTimeStep(bool enable,bool tempEnable) {
    List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_Enable_Activity;
    value[1] =  (enable ? 1 : 0);
    value[2] =  (tempEnable ? 1 : 0);
    _crcValue(value);
    return Uint8List.fromList(value);
  }


  ///停止实时计步
  static Uint8List stopGo() {
    List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_Enable_Activity;
    value[1] = 0;
    _crcValue(value);
    return Uint8List.fromList(value);
  }



  ///设置个人信息
  ///Set user profile
  static Uint8List SetPersonalInfo(MyPersonalInfo info) {
    List<int> value = _generateInitValue();
    int male = info.sex;
    int age = info.age;
    int height = info.height;
    int weight = info.weight;
    int stepLength = info.stepLength;
    value[0] = DeviceConst.CMD_Set_UseInfo;
    value[1] =  male;
    value[2] =  age;
    value[3] =  height;
    value[4] =  weight;
    value[5] =  stepLength;
    _crcValue(value);
    return Uint8List.fromList(value);
  }


  ///获取个人信息
  ///Get user's personal information
  static Uint8List GetPersonalInfo() {
    List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_GET_USERINFO;
    _crcValue(value);
    return Uint8List.fromList(value);
  }


  ///设置设备时间
  ///Set Device Time
  static Uint8List SetDeviceTime(DateTime dateTime) {
    final List<int> value = _generateInitValue();
    final int year = dateTime.year;
    final int month = dateTime.month;
    final int day = dateTime.day;
    final int hour = dateTime.hour;
    final int minute = dateTime.minute;
    final int second = dateTime.second;
    value[0] = DeviceConst.CMD_SET_TIME;
    value[1] = _getBcdValue(year);
    value[2] = _getBcdValue(month);
    value[3] = _getBcdValue(day);
    value[4] = _getBcdValue(hour);
    value[5] = _getBcdValue(minute);
    value[6] = _getBcdValue(second);
    _crcValue(value);
    return Uint8List.fromList(value);
  }


  ///获取设备时间
  ///Get device time
  static Uint8List GetDeviceTime() {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_GET_TIME;
    _crcValue(value);
    return Uint8List.fromList(value);
  }


  ///99: 删除步数详细数据
  ///0:读最近的步数详细数据
  ///1：读指定位置的步数详细数据
  ///2：继续上次读的位置下一段数据
  static Uint8List GetDetailActivityDataWithMode(int mode) {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_Get_DetailData;
    if(99==mode){
      value[1] =  0x99;
    }else{
      value[1] =  mode;
    }
    _crcValue(value);
    return Uint8List.fromList(value);
  }

  ///自动测试温度数据
  ///0:读最近的温度详细数据 1：读指定位置的步数详细数据 2：继续上次读的位置下一段数据 99: 删除温度数据
  ///Automatic testing of temperature data
  ///0: Read the latest temperature detailed data 1: Read the detailed data of the number of steps at the specified location 2: Continue with the previous read position and the next section of data 99: Delete temperature data
  static Uint8List GetTemperature_historyDataWithMode(int mode) {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.Temperature_history;
    if(99==mode){
      value[1] =  0x99;
    }else{
      value[1] =  mode;
    }
    _crcValue(value);
    return Uint8List.fromList(value);
  }


  ///手动测试温度数据
  ///0:读最近的温度详细数据 1：读指定位置的步数详细数据 2：继续上次读的位置下一段数据 99: 删除温度数据
  ///Manual testing of temperature data
  ///0: Read the latest temperature detailed data 1: Read the detailed data of the number of steps at the specified location 2: Continue with the previous read position and the next section of data 99: Delete temperature data
  static Uint8List GetAxillaryTemperatureDataWithMode(int mode) {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.GetAxillaryTemperatureDataWithMode;
    if(99==mode){
      value[1] =  0x99;
    }else if(0==mode){
      value[1] =  0x00;
    }else if(1==mode){
      value[1] =  0x01;
    }else{
      value[1] =  0x02;
    }
    _crcValue(value);
    return Uint8List.fromList(value);
  }


  ///获取某天总数据
  ///0:表⽰是从最新的位置开始读取(最多50组数据)  2:表⽰接着读取(当数据总数⼤于50的时候) 0x99:表⽰删除所有运动数据
  ///Obtain total data for a certain day
  ///0: Table 1 starts reading from the latest position (up to 50 sets of data) 2: Table 2 continues reading (when the total number of data exceeds 50) 0x99: Table 1 deletes all motion data
  static Uint8List GetTotalActivityDataWithMode(int mode) {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_Get_TotalData;
    if(99==mode){
      value[1] =  0x99;
    }else if(0==mode){
      value[1] =  0x00;
    }else if(1==mode){
      value[1] =  0x01;
    }else{
      value[1] =  0x02;
    }
    _crcValue(value);
    return Uint8List.fromList(value);
  }



  ///进入dfu模式
  ///Entering dfu mode
  static Uint8List enterOTA() {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_Start_Ota;
    _crcValue(value);
    return Uint8List.fromList(value);
  }


  ///获取设备版本号
  ///Read software version number
  static Uint8List GetDeviceVersion() {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_Get_Version;
    _crcValue(value);
    return Uint8List.fromList(value);
  }


  ///读取/删除闹钟 99删除闹钟，0读取闹钟
  ///Read/delete alarm clock 99 Delete alarm clock, 0 Read alarm clock
  static Uint8List GetAlarmClock(int mode) {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_Get_Clock;
    value[1] =  mode;
    _crcValue(value);
    return Uint8List.fromList(value);
  }

  static bool Qrcode = false;

  ///正常页面下手环进二维码绑定页面
  ///Under normal pages, manually loop in the QR code to bind the page
  static Uint8List lockScreen(){
    Qrcode=true;
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_QrCode;
    value[1] =  0x80;
    _crcValue(value);
    return Uint8List.fromList(value);
  }

  ///二维码页面下解锁手环进主页面
  ///Unlock the bracelet under the QR code page and enter the main page
  static Uint8List unLockScreen(){
    Qrcode=false;
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_QrCode;
    value[1] =  0x81;
    _crcValue(value);
    return Uint8List.fromList(value);
  }

  ///ECG+PPG查询测量状态
  ///ECG+PPG query measurement status
  static Uint8List GetEcgPpgStatus(){
    final List<int> value = _generateInitValue();
    value[0]=DeviceConst.GetEcgPpgStatus;
    _crcValue(value);
    return Uint8List.fromList(value);
  }


  ///设置运动提醒
  ///Set up exercise periods
  static Uint8List SetSedentaryReminder(MySedentaryReminder activityAlarm) {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_Set_ActivityAlarm;
    value[1] = _getBcdValue(activityAlarm.startHour);
    value[2] = _getBcdValue(activityAlarm.startMinute);
    value[3] = _getBcdValue(activityAlarm.endHour);
    value[4] = _getBcdValue(activityAlarm.endMinute);
    value[5] =  activityAlarm.week;
    value[6] =  activityAlarm.intervalTime;
    value[7] =  (activityAlarm.leastStep & 0xff);
    value[8] =  (activityAlarm.enable ? 1 : 0);
    _crcValue(value);
    return Uint8List.fromList(value);
  }


  ///读取运动时段
  ///Read sport period
  static Uint8List GetSedentaryReminder() {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_Get_ActivityAlarm;
    _crcValue(value);
    return Uint8List.fromList(value);
  }


  ///恢复出厂设置
  ///Restore factory settings
  static Uint8List Reset() {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_Reset;
    _crcValue(value);
    return Uint8List.fromList(value);
  }


  ///获取设备mac地址
  ///Read MAC address
  static Uint8List GetDeviceMacAddress() {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_Get_Address;
    _crcValue(value);
    return Uint8List.fromList(value);
  }


  ///获取设备电量
  ///Read device power
  static Uint8List GetDeviceBatteryLevel() {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_Get_BatteryLevel;
    _crcValue(value);
    return Uint8List.fromList(value);
  }


  ///重启设备
  ///MCU soft reset command
  static Uint8List MCUReset() {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_Mcu_Reset;
    _crcValue(value);
    return Uint8List.fromList(value);
  }

  ///设置设备名字
  ///Set device name
  static Uint8List SetDeviceName(String strDeviceName) {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_Set_Name;
    int length = strDeviceName.length > 14 ? 14 : strDeviceName.length;
    for (int i = 0; i < length; i++) {
      value[i + 1] =  strDeviceName.codeUnitAt(i);
    }
    _crcValue(value);
    return Uint8List.fromList(value);
  }


  ///获取设备名称
  ///Read Bluetooth device name
  static Uint8List GetDeviceName() {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_Get_Name;
    _crcValue(value);
    return Uint8List.fromList(value);
  }


  ///单独设置距离单位
  ///Set distance units separately
  static Uint8List SetDistanceUnit(bool km) {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_Set_DeviceInfo;
    value[1] =  km?0x81:0x80;
    _crcValue(value);
    return Uint8List.fromList(value);
  }

  ///单独设置是12小时还是24小时
  ///Is it set separately for 12 hours or 24 hours
  static Uint8List Settime(bool is12) {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_Set_DeviceInfo;
    value[2] =  is12?0x81:0x80;
    _crcValue(value);
    return Uint8List.fromList(value);
  }

  ///单独设置抬手亮屏开关
  ///Individually set the raise hand and light screen switch
  static Uint8List Hand_up_light_screen_switch(bool open) {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_Set_DeviceInfo;
    value[3] =  open?0x81:0x80;
    _crcValue(value);
    return Uint8List.fromList(value);
  }

  ///温度单位切换
  ///Temperature unit switching
  static Uint8List isFahrenheit(bool isFahrenheit) {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_Set_DeviceInfo;
    value[4] =  isFahrenheit?0x81:0x80;
    _crcValue(value);
    return Uint8List.fromList(value);
  }

  ///单独设置夜间模式
  ///Set night mode separately
  static Uint8List isNightmode(bool isNightmode) {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_Set_DeviceInfo;
    value[5] =  !isNightmode?0x81:0x80;
    _crcValue(value);
    return Uint8List.fromList(value);
  }


  ///设置表盘 1 - 10
  ///Set the dial separately 1 - 10
  static Uint8List dialSelection(int index) {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_Set_DeviceInfo;
    value[12] =  (0x80 + index);
    _crcValue(value);
    return Uint8List.fromList(value);
  }

  ///设置屏幕亮度 1 - 15
  ///Set screen brightness 1 - 15
  static Uint8List screenBrightness(int index) {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_Set_DeviceInfo;
    value[11] =  (0x80 + index);
    _crcValue(value);
    return Uint8List.fromList(value);
  }

  ///语言切换 0 英文 1 中文
  ///Language switch 0 English 1 Chinese
  static Uint8List languageSwitch(int index) {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_Set_DeviceInfo;
    value[14] =  (0x80 + index);
    _crcValue(value);
    return Uint8List.fromList(value);
  }

  ///设置设备信息
  ///Set basic parameters of Bracelet
  static Uint8List SetDeviceInfo(MyDeviceInfo deviceBaseParameter) {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_Set_DeviceInfo;
    value[1] = (deviceBaseParameter.DistanceUnit ? 0x81 : 0x80);
    value[2] = (deviceBaseParameter.is12Hour ? 0x81 : 0x80);
    value[3] = (deviceBaseParameter.Hand_up_light_screen_switch ? 0x81 : 0x80);
    value[4] = (!deviceBaseParameter.Fahrenheit ? 0x81 : 0x80);
    value[5] = (deviceBaseParameter.Nightmode ? 0x81 : 0x80);
    value[6] = 0x80;
    value[9] = (0x80 + deviceBaseParameter.baseheart);
    value[11] = (0x80 + deviceBaseParameter.screenBrightness);
    value[12] = (0x80 + deviceBaseParameter.indexDial);
    value[14] = (0x80 + deviceBaseParameter.languages);
    _crcValue(value);
    return Uint8List.fromList(value);
  }

  ///设置设备id
  ///SetDeviceID
  static Uint8List SetDeviceID(String deviceId) {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_Set_DeviceID;
    for (int i = 0; i < 6; i++) {
      value[i + 1] =  deviceId.codeUnitAt(i);
    }
    _crcValue(value);
    return Uint8List.fromList(value);
  }


  static Uint8List SetMusicStatus(bool start) {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.Enter_photo_modeback;
    value[1]=0x03;
    value[2] = start?0x04:0x05;
    _crcValue(value);
    return Uint8List.fromList(value);
  }


  static Uint8List SendMusicname(String name) {
    List<int> titleValue = name.isEmpty?[0]: _getInfoValue(name, 12);
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.Enter_photo_modeback;
    value[1] = 0x03;
    value[2] =  0xFE;
    arrayCopy(titleValue, 0, value, 3, titleValue.length);
    _crcValue(value);
    return Uint8List.fromList(value);
  }

  static bool StartDeviceMeasurementWithType=false;

  ///健康测量控制
  ///Health measurement control
  static Uint8List HealthMeasurementWithDataType(int dataType,bool open) {
    StartDeviceMeasurementWithType=open;
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.MeasurementWithType;
    value[1]=dataType;
    value[2] = open?0x01:0x00;
    _crcValue(value);
    return Uint8List.fromList(value);
  }

  ///APP更新天气状态
  ///APP updates weather status
  static Uint8List setWeather(WeatherData weatherData){
    final List<int> value = _generateValue(42);
    value[0]= DeviceConst.Weather;
    value[1]=  weatherData.weatherId;
    value[2]=  weatherData.tempNow;
    value[3]=  weatherData.tempHigh;
    value[4]=  weatherData.tempLow;
    List<int> infoValue = weatherData.cityName.isEmpty ? [0] : _getInfoValue(weatherData.cityName, 32);
    value[7]= infoValue.length;
    arrayCopy(infoValue, 0, value, 8, infoValue.length);
    _crcValue(value);
    return Uint8List.fromList(value);
  }

  static Uint8List SetBraceletdial(int mode) {
    isRuning=true;
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.Braceletdial;
    value[1] = mode;
    _crcValue(value);
    return Uint8List.fromList(value);
  }


  static Uint8List GetBraceletdial() {
    isRuning=false;
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.Braceletdial;
    value[1] = 0x00;
    value[2] = 0x01;
    _crcValue(value);
    return Uint8List.fromList(value);
  }

  ///获得HRV测试数据
  ///Get HRV test data
  static Uint8List GetHRVDataWithMode(int mode) {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_Get_HrvTestData;
    if(99==mode){
      value[1] =  0x99;
    }else if(0==mode){
      value[1] =  0x00;
    }else if(1==mode){
      value[1] =  0x01;
    }else{
      value[1] =  0x02;
    }
    _crcValue(value);
    return Uint8List.fromList(value);
  }

  ///读取女性健康信息
  ///Reading Women's Health Information
  static Uint8List readWomenHealth(){
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.WomenHealth;
    value[1] = 0xff;
    _crcValue(value);
    return Uint8List.fromList(value);
  }



  ///设置女性健康
  ///Setting up women's health
  static Uint8List setWomenHealth(DateTime date,int period,int length){
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.WomenHealth;
    value[1] = _getBcdValue(date.year - 2000);
    value[2] = _getBcdValue(date.month);
    value[3] = _getBcdValue(date.day);
    value[4] = period;// 2-7
    value[5] = length;//21-35
    _crcValue(value);
    return Uint8List.fromList(value);
  }


  static bool pregnancyCycleRead = false;
  ///读取怀孕周期
  ///Reading pregnancy cycles
  static Uint8List readPregnancyCycle(){
    pregnancyCycleRead = true;
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.PregnancyCycle;
    value[1] = 0xff;
    _crcValue(value);
    return Uint8List.fromList(value);
  }

  ///设置怀孕周期
  ///Set pregnancy cycle
  static Uint8List setPregnancyCycle(DateTime date){
    pregnancyCycleRead = false;
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.PregnancyCycle;
    value[3] = _getBcdValue(date.year - 2000);
    value[4] = _getBcdValue(date.month);
    value[5] = _getBcdValue(date.day);
    _crcValue(value);
    return Uint8List.fromList(value);
  }

  static bool isSettingSocial=false;
  static Uint8List setSocialSetting(int interval,int duration,int rssi){
    isSettingSocial=true;
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_SET_SOCIAL;
    value[1] =  1;//1设置，0读取
    value[2]=  interval;
    value[3]=  duration;
    value[4]=  rssi;
    _crcValue(value);
    return Uint8List.fromList(value);
  }

  static Uint8List getSocialSetting(){
    isSettingSocial=false;
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_SET_SOCIAL;
    value[1] =  0;//1设置，0读取
    _crcValue(value);
    return Uint8List.fromList(value);
  }

  ///设置自动检测心率时段
  ///Set automatic heart rate detection period
  static Uint8List SetAutomaticHRMonitoring(MyAutomaticHRMonitoring autoHeart) {
    final List<int> value = _generateInitValue();
    int time = autoHeart.time;
    value[0] = DeviceConst.CMD_Set_AutoHeart;
    value[1] =  autoHeart.open;
    value[2] = _getBcdValue(autoHeart.startHour);
    value[3] = _getBcdValue(autoHeart.startMinute);
    value[4] = _getBcdValue(autoHeart.endHour);
    value[5] = _getBcdValue(autoHeart.endMinute);
    value[6] =  autoHeart.week;
    value[7] =  (time & 0xff);
    value[8] =  ((time >> 8) & 0xff);
    value[9] = autoHeart.type;//
    _crcValue(value);
    return Uint8List.fromList(value);
  }

  ///读取自动检测心率时段
  ///1 心率 2 血氧 3 温度 4 HRV
  ///Read auto detect heart rate period
  ///1 Heart rate 2 Blood oxygen 3 Temperature 4 HRV
  static Uint8List GetAutomaticHRMonitoring(int type) {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_Get_AutoHeart;
    value[1] = type;
    _crcValue(value);
    return Uint8List.fromList(value);
  }

  ///获取多模式运动数据
  ///mode 0:表⽰是从最新的位置开始读取(最多50组数据)  2:表⽰接着读取(当数据总数⼤于50的时候) 0x99:表⽰删除所有GPS数据
  ///Obtain multimodal motion data
  ///Mode 0: Table 1 starts reading from the latest position (up to 50 sets of data) 2: Table 2 continues reading (when the total number of data exceeds 50) 0x99: Table 1 deletes all GPS data
  static Uint8List GetActivityModeDataWithMode(int mode) {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_Get_SPORTData;
    value[1] =  mode;
    _crcValue(value);
    return Uint8List.fromList(value);
  }


  static Uint8List LanguageSwitching(bool isEglish) {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.LanguageSwitching;
    value[1] = 0x01;
    value[2] = isEglish?0x00:0x01;
    _crcValue(value);
    return Uint8List.fromList(value);
  }

  ///获得单次心率数据（间隔测试心率）
  ///Obtain single heart rate data (interval test heart rate)
  static Uint8List GetStaticHRWithMode(int mode) {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_Get_OnceHeartData;
    value[1] = mode;
    _crcValue(value);
    return Uint8List.fromList(value);
  }

  ///获得心率数据
  ///Get heart rate data
  static Uint8List GetDynamicHRWithMode(int Number) {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_Get_HeartData;
    value[1] =  Number;
    _crcValue(value);
    return Uint8List.fromList(value);
  }
  ///获得血氧数据
  ///Get blood oxygen data
  static Uint8List GetBloodOxygen(int Number) {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_Get_Blood_oxygen;
    value[1] =  Number;
    _crcValue(value);
    return Uint8List.fromList(value);
  }

  ///获得血氧数据（自动测试）
  ///Obtain blood oxygen data (automatic testing)
  static Uint8List GetAutoBloodOxygen(int Number) {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_Get_Auto_Blood_oxygen;
    value[1] =  Number;
    _crcValue(value);
    return Uint8List.fromList(value);
  }



  ///设置目标步数
  ///Set target steps
  static Uint8List SetStepGoal(int stepGoal,int targetExecutionTime,int distance,int calorie,int sleepTime) {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_Set_Goal;
    value[4] =  ((stepGoal >> 24) & 0xff);
    value[3] =  ((stepGoal >> 16) & 0xff);
    value[2] =  ((stepGoal >> 8) & 0xff);
    value[1] =  ((stepGoal) & 0xff);
    value[6] =  ((targetExecutionTime >> 8) & 0xff);
    value[5] =  ((targetExecutionTime) & 0xff);
    value[8] =  ((distance >> 8) & 0xff);
    value[7] =  ((distance) & 0xff);
    value[10] =  ((calorie >> 8) & 0xff);
    value[9] =  ((calorie) & 0xff);
    value[12] =  ((sleepTime >> 8) & 0xff);
    value[11] =  ((sleepTime) & 0xff);
    _crcValue(value);
    return Uint8List.fromList(value);
  }

  ///读取目标步数
  ///Read target steps
  static Uint8List GetStepGoal() {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_Get_Goal;
    _crcValue(value);
    return Uint8List.fromList(value);
  }


  ///读取手环基本参数
  ///Read basic parameters of Bracelet
  static Uint8List GetDeviceInfo() {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_Get_DeviceInfo;
    _crcValue(value);
    return Uint8List.fromList(value);
  }


  ///第三方提醒命令
  ///Third party reminder order
  static Uint8List setNotifyData(Notifier sendData) {
    String info = sendData.info;
    List<int>infoValue = info.isEmpty ? [0] : _getInfoValue(info, 60);
    List<int> value = _generateValue(infoValue.length + 3);
    value[0] = DeviceConst.CMD_Notify;
    value[1] = sendData.type == 12 ? 0xff:sendData.type;
    value[2] =  infoValue.length;
    arrayCopy(infoValue, 0, value, 3, infoValue.length);
    return Uint8List.fromList(value);
  }

  ///设置温度修正值
  static Uint8List SetTemperatureCorrectionValue(int tempValue) {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_Set_TemperatureCorrection;
    value[1] = 1;
    List<int>tempArray = intToint(tempValue);
    value[2] = tempArray[1];
    value[3] = tempArray[0];
    _crcValue(value);
    return Uint8List.fromList(value);
  }

  static Uint8List Setpass(int tempValue) {
    final List<int> value = _generateInitValue();
    value[0] = 0x3c;
    value[1] = 0x73;
    value[2] = 0x24;
    value[3] = 0x89;
    value[4] = 0xa5;
    value[5] = 0xb4;
    value[6] = 0xc7;
    _crcValue(value);
    return Uint8List.fromList(value);
  }


  static List<int> intToint(int num) {
    return [((num >> 8) & 0xff),(num & 0xff)];
  }

  static int intArrayToInt(List<int>arr) {
    int targets = ((arr[1] & 0xff) | ((arr[0] << 8) & 0xff00));
    return targets;
  }

  ///设置手环参数（新增加）0 右手 1 左手
  ///Set bracelet parameters (newly added)
  static Uint8List setNewDeviceInfo(int ecg) {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_Set_NewDeviceInfo;
    value[1] =  (0x80 + ecg);
    _crcValue(value);
    return Uint8List.fromList(value);
  }

  ///获取手环参数（新增加）0 右手 1 左手
  ///Get bracelet parameters (newly added)
  static Uint8List getNewDeviceInfo() {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.CMD_Get_NewDeviceInfo;
    _crcValue(value);
    return Uint8List.fromList(value);
  }


  ///进入拍照模式
  ///Entering photo mode
  static Uint8List EnterPhotoMode() {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.Enter_photo_mode;
    _crcValue(value);
    return Uint8List.fromList(value);
  }

  ///关闭拍照模式退出到主界面
  ///Turn off the photographing mode and exit to the main interface
  static Uint8List ExitPhotoMode() {
    final List<int> value = _generateInitValue();
    value[0] = DeviceConst.Exit_photo_mode;
    _crcValue(value);
    return Uint8List.fromList(value);
  }

}
